using Extensibility;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Vbe.Interop;
using System.Windows.Forms;
using Microsoft.Office.Core;
using System.Diagnostics;
using static VBACodeingTool.VBEHelper;
using static VBACodeingTool.MouseHelper;
using System.Drawing;
using System.Threading;
using System.Xml.Linq;

namespace VBACodeingTool
{
    [ComVisible(true), Guid("D4BB8B37-ECC2-49BD-809B-A2E78E9E1C81"), ProgId("VBACodeingTool.Connect")]
    public class Connect : IDTExtensibility2
    {
        VBE _applicationObject;
        AddIn _addInInstance;
        CommandBar _commandBarMainMeun;
        CommandBarPopup _commandBarPopupAppMain;
        CommandBarButton _commandBarButtonShortCut;
        CommandBarButton _commandBarButtonReload;
        KeyboardHook _keyboardHook;
        Popup popup;
        public void OnConnection(object Application, ext_ConnectMode ConnectMode, object AddInInst, ref Array custom)
        {
            if (this._addInInstance == null)
            {

                this._addInInstance = (AddIn)AddInInst;
                this._applicationObject = (VBE)Application;
                ProgramInstanceManager.VBE = this._applicationObject;
                ProgramInstanceManager.AddIn = this._addInInstance;
            }
            SetStaticObject();
            this._commandBarMainMeun = this._applicationObject.CommandBars[1];
            this._commandBarPopupAppMain = (CommandBarPopup)this._commandBarMainMeun.Controls.Add(MsoControlType.msoControlPopup, 1, 1, 7, 1);
            this._commandBarPopupAppMain.Caption = "VBACodeingTool";
            this._commandBarButtonShortCut = (CommandBarButton)this._commandBarPopupAppMain.Controls.Add(MsoControlType.msoControlButton, 1, 1, 1);
            this._commandBarButtonShortCut.Caption = "关闭快捷键";
            this._commandBarButtonShortCut.Click += _commandBarButton_Click;
            this._commandBarButtonReload = (CommandBarButton)this._commandBarPopupAppMain.Controls.Add(MsoControlType.msoControlButton, 1, 1, 1);
            this._commandBarButtonReload.Caption = "重新加载代码";
            this._commandBarButtonReload.Click += _commandBarButtonReload_Click;           
        }

        private void _commandBarButtonReload_Click(CommandBarButton Ctrl, ref bool CancelDefault)
        {
            ProgramInstanceManager.CodeDataManager = CodeLoaderHelper.CreateCodeManager();
        }

        private void _commandBarButton_Click(CommandBarButton Ctrl, ref bool CancelDefault)
        {
            if (_keyboardHook.isInstallHook())
            {
                _keyboardHook.uninstallHook();
                Ctrl.Caption = "开启快捷键";
                return;
            }
            _keyboardHook.installHook();
            Ctrl.Caption = "关闭快捷键";
        }

        public void OnDisconnection(ext_DisconnectMode RemoveMode, ref Array custom)
        {
            Debug.WriteLine("addIn OnDisconnection");
            _keyboardHook.uninstallHook();
            _keyboardHook.installMouseHook();
        }

        public void OnAddInsUpdate(ref Array custom)
        {
            Debug.WriteLine("addIn OnAddInsUpdate");
        }

        public void OnStartupComplete(ref Array custom)
        {
            Debug.WriteLine("addIn OnStartupComplete");
        }

        public void OnBeginShutdown(ref Array custom)
        {
            Debug.WriteLine("addIn OnBeginShutdown");
        }
        private void CopyToNext(Keys code, string shortCut)
        {
            CodeAndPosition codeAndPosition = VBEHelper.GetCodeAndPosition();
            string content = codeAndPosition.Content;
            if (content == string.Empty)
            {
                return;
            }
            VBEHelper.GetCurrentCodeModule().InsertLines(codeAndPosition.Position.endRow + 1, content);

        }
        private void MoveLineToUp(Keys code, string shortCut)
        {
            CodeAndPosition codeAndPosition = VBEHelper.GetCodeAndPosition();
            string content = codeAndPosition.Content;
            if (string.IsNullOrEmpty(content) || codeAndPosition.Position.startRow == 1)
            {
                return;
            }
            if (!codeAndPosition.IsMultiLines)
            {
                VBEHelper.GetCurrentCodeModule().InsertLines(codeAndPosition.Position.endRow - 1, content);
                VBEHelper.GetCurrentCodeModule().DeleteLines(codeAndPosition.Position.endRow + 1);
                VBEHelper.SetCurrentLineRowAndColumn(
                    codeAndPosition.Position.endRow - 1, codeAndPosition.Position.endColumn,
                    codeAndPosition.Position.endRow - 1, codeAndPosition.Position.endColumn);
            }
            else
            {
                int lines = codeAndPosition.Position.endRow - codeAndPosition.Position.startRow + 1;
                VBEHelper.GetCurrentCodeModule().InsertLines(codeAndPosition.Position.endRow - lines, content);
                VBEHelper.GetCurrentCodeModule().DeleteLines(codeAndPosition.Position.endRow + 1, lines);
                VBEHelper.SetCurrentLineRowAndColumn(
                    codeAndPosition.Position.startRow - 1, codeAndPosition.Position.startColumn,
                    codeAndPosition.Position.endRow - 1, codeAndPosition.Position.endColumn);
            }
        }
        private void MoveLineToDown(Keys code, string shortCut)
        {
            CodeAndPosition codeAndPosition = VBEHelper.GetCodeAndPosition();
            string content = codeAndPosition.Content;
            if (string.IsNullOrEmpty(content) || codeAndPosition.Position.endRow == VBEHelper.GetCurrentCodeModule().CountOfLines)
            {
                return;
            }
            if (!codeAndPosition.IsMultiLines)
            {
                VBEHelper.GetCurrentCodeModule().InsertLines(codeAndPosition.Position.endRow + 2, content);
                VBEHelper.GetCurrentCodeModule().DeleteLines(codeAndPosition.Position.endRow);
                VBEHelper.SetCurrentLineRowAndColumn(
                    codeAndPosition.Position.endRow + 1, codeAndPosition.Position.endColumn,
                    codeAndPosition.Position.endRow + 1, codeAndPosition.Position.endColumn);
            }
            else
            {
                int lines = codeAndPosition.Position.endRow - codeAndPosition.Position.startRow + 1;
                VBEHelper.GetCurrentCodeModule().InsertLines(codeAndPosition.Position.endRow + lines, content);
                VBEHelper.GetCurrentCodeModule().DeleteLines(codeAndPosition.Position.endRow - lines + 1, lines);
                VBEHelper.SetCurrentLineRowAndColumn(
                    codeAndPosition.Position.startRow + lines - 1, codeAndPosition.Position.startColumn,
                    codeAndPosition.Position.endRow + lines - 1, codeAndPosition.Position.endColumn);
            }
        }
        private  void ShowCodeTip(Keys code, string shortCut)
        {
            FromHelper.HitCode(code);
        }
        private void SetShortCut()
        {
            RegisterKey copyRegisterKey = new RegisterKey(true, false, false, Keys.D);
            copyRegisterKey.SetDelegate(new CallBackShortCutCommand(CopyToNext));
            ProgramInstanceManager.ShortCutManager.AddShortCut(copyRegisterKey);

            RegisterKey moveToUpRegisterKey = new RegisterKey(true, false, true, Keys.W);
            moveToUpRegisterKey.SetDelegate(new CallBackShortCutCommand(MoveLineToUp));
            ProgramInstanceManager.ShortCutManager.AddShortCut(moveToUpRegisterKey);

            RegisterKey moveToDownRegisterKey = new RegisterKey(true, false, true, Keys.S);
            moveToDownRegisterKey.SetDelegate(new CallBackShortCutCommand(MoveLineToDown));
            ProgramInstanceManager.ShortCutManager.AddShortCut(moveToDownRegisterKey);

            RegisterKey codeTipRegisterKey = new RegisterKey(true, false, false, Keys.Q);
            codeTipRegisterKey.SetDelegate(new CallBackShortCutCommand(ShowCodeTip));
            ProgramInstanceManager.ShortCutManager.AddShortCut(codeTipRegisterKey);
        }
        private void SetStaticObject()
        {
            _keyboardHook = new KeyboardHook((IntPtr)this._applicationObject.MainWindow.HWnd);
            ProgramInstanceManager.KeyboardHook = _keyboardHook;
            _keyboardHook.installHook();
            _keyboardHook.installMouseHook();
            ProgramInstanceManager.ShortCutManager = new ShortCutManager();
            popup = new Popup();
            ProgramInstanceManager.Popup = popup;
            SetShortCut();

            ProgramInstanceManager.CodeDataManager = CodeLoaderHelper.CreateCodeManager();
        }
    }
}
